Skip to content

개요

Timefit 예약 관리 시스템의 예약 생성, 조회, 수정, 취소 및 상태 관리를 위한 API입니다. 고객의 예약 신청부터 업체의 예약 승인/거절, 완료 처리까지 전체 예약 라이프사이클을 관리합니다.

API 목록

구분API 명설명
고객 예약예약 신청고객이 업체에 예약을 신청합니다
고객 예약내 예약 목록 조회고객이 자신의 예약 목록을 조회합니다
고객 예약예약 상세 조회특정 예약의 상세 정보를 조회합니다
고객 예약예약 수정예약 정보를 수정합니다
고객 예약예약 취소예약을 취소합니다
업체 예약받은 예약 신청 조회업체가 받은 예약 신청을 조회합니다
업체 예약예약 승인/거절예약 신청을 승인하거나 거절합니다
업체 예약예약 상태 변경예약을 완료 또는 노쇼 처리합니다
업체 예약예약 캘린더 조회업체의 예약 현황을 캘린더 형태로 조회합니다
공통업체 조회 (고객용)고객이 예약하고자 하는 업체 정보를 조회합니다

1. 예약 신청

고객이 업체에 예약을 신청합니다.

Request

Request Syntax

bash
curl -X POST https://{SERVER_URL}/api/reservations \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "businessId": "660e8400-e29b-41d4-a716-446655440001",
    "availableSlotId": "770e8400-e29b-41d4-a716-446655440002",
    "reservationDate": "2024-06-15",
    "reservationTime": "14:00",
    "durationMinutes": 60,
    "selectedOptions": [
      {
        "optionId": "880e8400-e29b-41d4-a716-446655440003",
        "optionName": "커트",
        "price": 25000
      }
    ],
    "notes": "앞머리 짧게 잘라주세요",
    "customerName": "김고객",
    "customerPhone": "01098765432"
  }'
메서드요청 URL
POSThttps://{SERVER_URL}/api/reservations

Request Header

파라미터타입필수여부설명
AuthorizationString필수Bearer
Content-TypeString필수application/json

Request Elements

필드타입필수설명예시제약사항
businessIdstringY업체 ID (UUID)660e8400-e29b-41d4...UUID 형식
availableSlotIdstringY예약 가능 슬롯 ID770e8400-e29b-41d4...UUID 형식
reservationDatestringY예약 날짜2024-06-15YYYY-MM-DD 형식, 오늘 이후
reservationTimestringY예약 시간14:00HH:mm 형식
durationMinutesintegerY예약 지속 시간(분)6015분 단위, 최소 15분
selectedOptionsarrayN선택한 서비스 옵션[]배열
selectedOptions[].optionIdstringY옵션 ID880e8400-e29b-41d4...UUID 형식
selectedOptions[].optionNamestringY옵션명커트-
selectedOptions[].priceintegerY옵션 가격250000 이상
notesstringN요청사항앞머리 짧게 잘라주세요500자 이하
customerNamestringY고객 이름김고객2-50자
customerPhonestringY고객 연락처0109876543201X-XXXX-XXXX 형식

Response

Response Syntax (201 Created)

json
{
  "success": true,
  "message": "예약이 완료되었습니다",
  "data": {
    "reservationId": "990e8400-e29b-41d4-a716-446655440004",
    "reservationNumber": "RES-20240615-001",
    "status": "PENDING",
    "businessInfo": {
      "businessId": "660e8400-e29b-41d4-a716-446655440001",
      "businessName": "홍길동 미용실",
      "address": "서울시 강남구 테헤란로 123",
      "contactPhone": "0212345678"
    },
    "reservationDetails": {
      "date": "2024-06-15",
      "time": "14:00",
      "durationMinutes": 60,
      "selectedOptions": [
        {
          "optionId": "880e8400-e29b-41d4-a716-446655440003",
          "optionName": "커트",
          "price": 25000
        }
      ],
      "totalPrice": 25000,
      "notes": "앞머리 짧게 잘라주세요"
    },
    "customerInfo": {
      "customerId": "440e8400-e29b-41d4-a716-446655440006",
      "customerName": "김고객",
      "customerPhone": "01098765432"
    },
    "createdAt": "2024-06-07T12:30:00Z",
    "updatedAt": "2024-06-07T12:30:00Z"
  }
}

Response Elements

필드타입필수여부설명
reservationIdstring필수예약 ID (UUID)
reservationNumberstring필수예약 번호
statusstring필수예약 상태 (PENDING, CONFIRMED, COMPLETED, CANCELLED, NO_SHOW)
businessInfoobject필수업체 정보
reservationDetailsobject필수예약 상세 정보
customerInfoobject필수고객 정보

Error Response

에러 코드상태 코드메시지발생 상황
BUSINESS_NOT_FOUND404"업체 정보를 찾을 수 없습니다"존재하지 않는 업체
SLOT_NOT_AVAILABLE409"해당 시간대는 예약할 수 없습니다"슬롯 예약 불가
SLOT_ALREADY_BOOKED409"이미 예약된 시간대입니다"슬롯 중복 예약
VALIDATION_ERROR400"입력값이 올바르지 않습니다"필드 검증 실패
BUSINESS_CLOSED400"해당 날짜는 영업일이 아닙니다"영업시간 외 예약

2. 내 예약 목록 조회

고객이 자신의 예약 목록을 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/reservations?status=PENDING&page=1&size=10 \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/reservations

Query Parameters

파라미터타입필수설명예시기본값
statusstringN예약 상태 필터PENDING, CONFIRMED전체
startDatestringN조회 시작 날짜2024-06-0130일 전
endDatestringN조회 종료 날짜2024-06-30오늘
businessIdstringN특정 업체 필터660e8400-e29b...전체
pageintegerN페이지 번호11
sizeintegerN페이지 크기1020

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약 목록 조회가 완료되었습니다",
  "data": {
    "reservations": [
      {
        "reservationId": "990e8400-e29b-41d4-a716-446655440004",
        "reservationNumber": "RES-20240615-001",
        "status": "CONFIRMED",
        "businessInfo": {
          "businessId": "660e8400-e29b-41d4-a716-446655440001",
          "businessName": "홍길동 미용실",
          "logoUrl": "<https://example.com/logo.jpg>"
        },
        "reservationDetails": {
          "date": "2024-06-15",
          "time": "14:00",
          "durationMinutes": 60,
          "selectedOptions": [
            {
              "optionName": "커트",
              "price": 25000
            }
          ],
          "totalPrice": 25000
        },
        "createdAt": "2024-06-07T12:30:00Z",
        "updatedAt": "2024-06-07T13:00:00Z"
      }
    ],
    "pagination": {
      "currentPage": 1,
      "totalPages": 5,
      "totalElements": 48,
      "size": 10,
      "hasNext": true,
      "hasPrevious": false
    }
  }
}

3. 예약 상세 조회

특정 예약의 상세 정보를 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/reservations/{reservationId} \\
  -H "Authorization: Bearer {accessToken}"

Path Parameters

파라미터타입필수설명예시
reservationIdstringY예약 ID (UUID)990e8400-e29b-41d4...

Response

Response Syntax (200 OK)

예약 신청과 동일한 응답 구조에 상태 변경 이력이 추가됩니다.

json
{
  "success": true,
  "message": "예약 상세 조회가 완료되었습니다",
  "data": {
    "reservationId": "990e8400-e29b-41d4-a716-446655440004",
    "reservationNumber": "RES-20240615-001",
    "status": "CONFIRMED",
    "businessInfo": {
      "businessId": "660e8400-e29b-41d4-a716-446655440001",
      "businessName": "홍길동 미용실",
      "address": "서울시 강남구 테헤란로 123",
      "contactPhone": "0212345678",
      "logoUrl": "<https://example.com/logo.jpg>"
    },
    "reservationDetails": {
      "date": "2024-06-15",
      "time": "14:00",
      "durationMinutes": 60,
      "selectedOptions": [
        {
          "optionId": "880e8400-e29b-41d4-a716-446655440003",
          "optionName": "커트",
          "price": 25000
        }
      ],
      "totalPrice": 25000,
      "notes": "앞머리 짧게 잘라주세요"
    },
    "customerInfo": {
      "customerId": "440e8400-e29b-41d4-a716-446655440006",
      "customerName": "김고객",
      "customerPhone": "01098765432"
    },
    "statusHistory": [
      {
        "status": "PENDING",
        "reason": "예약이 신청되었습니다",
        "changedAt": "2024-06-07T12:30:00Z",
        "changedBy": "customer"
      },
      {
        "status": "CONFIRMED",
        "reason": "예약이 승인되었습니다",
        "changedAt": "2024-06-07T13:00:00Z",
        "changedBy": "business"
      }
    ],
    "canModify": true,
    "canCancel": true,
    "cancelDeadline": "2024-06-14T14:00:00Z",
    "createdAt": "2024-06-07T12:30:00Z",
    "updatedAt": "2024-06-07T13:00:00Z"
  }
}

4. 예약 수정

예약 정보를 수정합니다.

Request

Request Syntax

bash
curl -X PUT https://{SERVER_URL}/api/reservations/{reservationId} \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "reservationDate": "2024-06-16",
    "reservationTime": "15:00",
    "notes": "앞머리와 옆머리 모두 짧게 잘라주세요",
    "reason": "일정 변경으로 인한 수정"
  }'

Request Elements

필드타입필수설명예시제약사항
reservationDatestringN변경할 예약 날짜2024-06-16YYYY-MM-DD 형식
reservationTimestringN변경할 예약 시간15:00HH:mm 형식
notesstringN변경할 요청사항앞머리와...500자 이하
reasonstringY수정 사유일정 변경으로...100자 이하

Response

Response Syntax (200 OK)

예약 상세 조회와 동일한 응답 구조를 반환합니다.


5. 예약 취소

예약을 취소합니다.

Request

Request Syntax

bash
curl -X DELETE https://{SERVER_URL}/api/reservations/{reservationId} \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "reason": "개인 사정으로 인한 취소"
  }'

Request Elements

필드타입필수설명예시제약사항
reasonstringY취소 사유개인 사정으로...100자 이하

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약이 취소되었습니다",
  "data": {
    "reservationId": "990e8400-e29b-41d4-a716-446655440004",
    "previousStatus": "CONFIRMED",
    "currentStatus": "CANCELLED",
    "reason": "개인 사정으로 인한 취소",
    "cancelledAt": "2024-06-07T14:00:00Z"
  }
}

6. 받은 예약 신청 조회 (업체용)

업체가 받은 예약 신청을 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/reservations?status=PENDING&date=2024-06-15 \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/reservations

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4...

Query Parameters

파라미터타입필수설명예시기본값
statusstringN예약 상태 필터PENDING, CONFIRMED전체
datestringN특정 날짜 필터2024-06-15오늘
startDatestringN조회 시작 날짜2024-06-017일 전
endDatestringN조회 종료 날짜2024-06-3030일 후
pageintegerN페이지 번호11
sizeintegerN페이지 크기1020

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약 목록 조회가 완료되었습니다",
  "data": {
    "businessInfo": {
      "businessId": "660e8400-e29b-41d4-a716-446655440001",
      "businessName": "홍길동 미용실"
    },
    "reservations": [
      {
        "reservationId": "990e8400-e29b-41d4-a716-446655440004",
        "reservationNumber": "RES-20240615-001",
        "status": "PENDING",
        "customerInfo": {
          "customerId": "440e8400-e29b-41d4-a716-446655440006",
          "customerName": "김고객",
          "customerPhone": "01098765432",
          "profileImageUrl": "<https://example.com/profile.jpg>"
        },
        "reservationDetails": {
          "date": "2024-06-15",
          "time": "14:00",
          "durationMinutes": 60,
          "selectedOptions": [
            {
              "optionName": "커트",
              "price": 25000
            }
          ],
          "totalPrice": 25000,
          "notes": "앞머리 짧게 잘라주세요"
        },
        "createdAt": "2024-06-07T12:30:00Z",
        "requiresAction": true
      }
    ],
    "pagination": {
      "currentPage": 1,
      "totalPages": 3,
      "totalElements": 25,
      "size": 10,
      "hasNext": true,
      "hasPrevious": false
    },
    "summary": {
      "totalToday": 8,
      "pendingCount": 3,
      "confirmedCount": 5,
      "totalRevenue": 200000
    }
  }
}

Error Response

에러 코드상태 코드메시지발생 상황
BUSINESS_NOT_FOUND404"업체 정보를 찾을 수 없습니다"존재하지 않는 업체
ACCESS_DENIED403"접근 권한이 없습니다"업체 구성원이 아님
VALIDATION_ERROR400"입력값이 올바르지 않습니다"파라미터 검증 실패

7. 예약 승인/거절 (업체용)

예약 신청을 승인하거나 거절합니다.

Request

Request Syntax

bash
curl -X PATCH https://{SERVER_URL}/api/businesses/{businessId}/reservations/{reservationId}/status \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "status": "CONFIRMED",
    "reason": "예약이 승인되었습니다"
  }'
메서드요청 URL
PATCHhttps://{SERVER_URL}/api/businesses/{businessId}/reservations/{reservationId}/status

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4...
reservationIdstringY예약 ID (UUID)990e8400-e29b-41d4...

Request Elements

필드타입필수설명예시
statusstringY변경할 상태CONFIRMED, CANCELLED
reasonstringN승인/거절 사유예약이 승인되었습니다

예약 상태 값

설명
CONFIRMED승인됨
CANCELLED거절됨

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약이 승인되었습니다",
  "data": {
    "reservationId": "990e8400-e29b-41d4-a716-446655440004",
    "previousStatus": "PENDING",
    "currentStatus": "CONFIRMED",
    "reason": "예약이 승인되었습니다",
    "updatedAt": "2024-06-07T13:00:00Z",
    "updatedBy": {
      "userId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "홍길동",
      "role": "OWNER"
    }
  }
}

Error Response

에러 코드상태 코드메시지발생 상황
RESERVATION_NOT_FOUND404"예약 정보를 찾을 수 없습니다"존재하지 않는 예약
RESERVATION_INVALID_STATUS400"현재 예약 상태에서는 처리할 수 없습니다"상태 변경 불가
ACCESS_DENIED403"접근 권한이 없습니다"업체 구성원이 아님
INSUFFICIENT_PERMISSION403"해당 작업을 수행할 권한이 없습니다"MEMBER 역할 제한

8. 예약 상태 변경 - 완료/노쇼 (업체용)

예약을 완료 또는 노쇼 처리합니다.

Request

Request Syntax

bash
curl -X PATCH https://{SERVER_URL}/api/businesses/{businessId}/reservations/{reservationId}/complete \\
  -H "Authorization: Bearer {accessToken}" \\
  -H "Content-Type: application/json" \\
  -d '{
    "status": "COMPLETED",
    "notes": "서비스가 정상적으로 완료되었습니다"
  }'
메서드요청 URL
PATCHhttps://{SERVER_URL}/api/businesses/{businessId}/reservations/{reservationId}/complete

Request Elements

필드타입필수설명예시
statusstringY완료 상태COMPLETED, NO_SHOW
notesstringN완료 메모서비스가 정상적으로...

완료 상태 값

설명
COMPLETED서비스 완료
NO_SHOW고객 노쇼

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약이 완료 처리되었습니다",
  "data": {
    "reservationId": "990e8400-e29b-41d4-a716-446655440004",
    "previousStatus": "CONFIRMED",
    "currentStatus": "COMPLETED",
    "notes": "서비스가 정상적으로 완료되었습니다",
    "completedAt": "2024-06-15T15:00:00Z",
    "completedBy": {
      "userId": "550e8400-e29b-41d4-a716-446655440000",
      "name": "홍길동",
      "role": "OWNER"
    }
  }
}

9. 예약 캘린더 조회 (업체용)

업체의 예약 현황을 캘린더 형태로 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/reservations/calendar?year=2024&month=6 \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/reservations/calendar

Query Parameters

파라미터타입필수설명예시기본값
yearintegerN조회 연도2024현재 연도
monthintegerN조회 월6현재 월

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "예약 캘린더 조회가 완료되었습니다",
  "data": {
    "businessInfo": {
      "businessId": "660e8400-e29b-41d4-a716-446655440001",
      "businessName": "홍길동 미용실"
    },
    "calendar": {
      "year": 2024,
      "month": 6,
      "days": [
        {
          "date": "2024-06-15",
          "dayOfWeek": 6,
          "isBusinessDay": true,
          "businessHours": {
            "openTime": "09:00",
            "closeTime": "18:00"
          },
          "reservations": [
            {
              "reservationId": "990e8400-e29b-41d4-a716-446655440004",
              "time": "14:00",
              "duration": 60,
              "status": "CONFIRMED",
              "customerName": "김고객",
              "serviceName": "커트",
              "price": 25000
            }
          ],
          "totalReservations": 5,
          "totalRevenue": 125000,
          "availableSlots": 8
        }
      ],
      "monthSummary": {
        "totalReservations": 150,
        "totalRevenue": 3750000,
        "averageDaily": 5,
        "busyDays": ["2024-06-15", "2024-06-22", "2024-06-29"]
      }
    }
  }
}

10. 업체 조회 (고객용)

고객이 예약하고자 하는 업체 정보를 조회합니다.

Request

Request Syntax

bash
curl -X GET https://{SERVER_URL}/api/businesses/{businessId}/public \\
  -H "Authorization: Bearer {accessToken}"
메서드요청 URL
GEThttps://{SERVER_URL}/api/businesses/{businessId}/public

Path Parameters

파라미터타입필수설명예시
businessIdstringY비즈니스 ID (UUID)660e8400-e29b-41d4...

Response

Response Syntax (200 OK)

json
{
  "success": true,
  "message": "업체 정보 조회가 완료되었습니다",
  "data": {
    "businessInfo": {
      "businessId": "660e8400-e29b-41d4-a716-446655440001",
      "businessName": "홍길동 미용실",
      "businessType": "미용실",
      "address": "서울시 강남구 테헤란로 123",
      "contactPhone": "0212345678",
      "description": "깔끔하고 세련된 미용실입니다",
      "logoUrl": "<https://example.com/logo.jpg>",
      "rating": 4.8,
      "reviewCount": 127
    },
    "businessHours": [
      {
        "dayOfWeek": 1,
        "dayName": "월요일",
        "openTime": "09:00",
        "closeTime": "18:00",
        "isClosed": false
      },
      {
        "dayOfWeek": 0,
        "dayName": "일요일",
        "openTime": null,
        "closeTime": null,
        "isClosed": true
      }
    ],
    "services": [
      {
        "serviceId": "aa0e8400-e29b-41d4-a716-446655440005",
        "serviceName": "기본 커트",
        "description": "기본적인 헤어커트 서비스입니다",
        "price": 25000,
        "duration": 60,
        "category": "기본",
        "imageUrl": "<https://example.com/cut.jpg>"
      }
    ],
    "policies": {
      "cancelDeadlineHours": 24,
      "modifyDeadlineHours": 24,
      "advanceBookingDays": 30
    }
  }
}

권한 체계 및 변경사항

업체 예약 관리 권한

역할예약 조회예약 승인/거절예약 완료/노쇼캘린더 조회
OWNER
MANAGER
MEMBER

권한 체크 로직 변경사항

기존 방식

sql
-- 기존: business.user_id 기반 소유권 체크
SELECT b.* FROM business b
WHERE b.id = ? AND b.user_id = ?

신규 방식

sql
-- 신규: user_business_role 테이블 기반 권한 체크
SELECT ubr.role FROM user_business_role ubr
WHERE ubr.user_id = ?
  AND ubr.business_id = ?
  AND ubr.is_active = true

API URL 변경사항

기존신규변경사항
/api/business/reservations/api/businesses/{businessId}/reservationsbusinessId 기반
사용자 기준 조회비즈니스별 조회명확한 리소스 구분

예약 상태 관리

예약 상태 전이도

PENDING → CONFIRMED → COMPLETED
    ↓         ↓
CANCELLED  CANCELLED
    ↓         ↓
    X      NO_SHOW

상태별 가능한 액션

현재 상태고객 가능 액션업체 가능 액션
PENDING수정, 취소승인, 거절
CONFIRMED취소완료, 노쇼, 취소
COMPLETED--
CANCELLED--
NO_SHOW--

예약 정책

항목기본값설명
취소 데드라인24시간 전예약 시간 24시간 전까지 취소 가능
수정 데드라인24시간 전예약 시간 24시간 전까지 수정 가능
선예약 기간30일최대 30일 후까지 예약 가능
당일 예약2시간 전예약 시간 2시간 전까지 당일 예약 가능

에러 코드 정의

예약 관련 에러

에러 코드HTTP Status메시지발생 상황
RESERVATION_NOT_FOUND404"예약 정보를 찾을 수 없습니다"존재하지 않는 예약
RESERVATION_INVALID_STATUS400"현재 예약 상태에서는 처리할 수 없습니다"상태 변경 불가
RESERVATION_DEADLINE_PASSED400"예약 변경/취소 가능 시간이 지났습니다"데드라인 초과
SLOT_NOT_AVAILABLE409"해당 시간대는 예약할 수 없습니다"슬롯 예약 불가
SLOT_ALREADY_BOOKED409"이미 예약된 시간대입니다"슬롯 중복 예약
BUSINESS_CLOSED400"해당 날짜는 영업일이 아닙니다"영업시간 외 예약
SERVICE_NOT_AVAILABLE400"선택하신 서비스는 현재 이용할 수 없습니다"비활성화된 서비스

권한 관련 에러

에러 코드HTTP Status메시지발생 상황
ACCESS_DENIED403"접근 권한이 없습니다"기본 권한 부족
INSUFFICIENT_PERMISSION403"해당 작업을 수행할 권한이 없습니다"역할별 권한 부족
NOT_BUSINESS_MEMBER403"해당 업체의 구성원이 아닙니다"업체 구성원 아님
NOT_RESERVATION_OWNER403"본인의 예약이 아닙니다"예약 소유권 없음

알림 및 이벤트

예약 관련 알림 이벤트

이벤트고객 알림업체 알림알림 내용
예약 신청✅ 신청 완료✅ 새 예약 신청예약번호, 날짜/시간, 서비스
예약 승인✅ 예약 확정-확정 안내, 업체 연락처
예약 거절✅ 예약 거절-거절 사유, 대안 제시
예약 수정✅ 수정 완료✅ 예약 변경변경 내용, 사유
예약 취소✅ 취소 완료✅ 예약 취소취소 사유, 환불 정보
예약 완료✅ 서비스 완료-리뷰 요청, 재방문 유도
예약 리마인더✅ 1일 전, 1시간 전✅ 당일 일정준비사항, 주의사항

데이터 무결성 및 비즈니스 규칙

예약 검증 규칙

  1. 시간 중복 방지: 동일 시간대에 슬롯 용량 초과 예약 방지
  2. 영업시간 검증: 업체 영업시간 내에서만 예약 가능
  3. 과거 날짜 방지: 현재 시간 이후로만 예약 가능
  4. 서비스 유효성: 활성화된 서비스만 예약 가능
  5. 데드라인 검증: 취소/수정 데드라인 준수